
//
// Copyright 2009 Arne Halvorsen (arne.halvorsen@gmail.com)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// Project page: http://code.google.com/p/mf4j/

//
// 091116a- aha42 - Starts in line change tracking.
// 091116b- aha42 - createPhotoUrlSpec(String, String, String, String, String),
//                  createPhotoUrlSpec(String, String, String, String) and
//                  createOrgPhotoUrlSpec(String, String, String, String, String).
// 091116c- aha42 - createPhotoUrlSpec(FlickrObject photoFo) and
//                  createPhotoUrlSpec(FlickrObject photoFo, String).
// 091116d- aha42 - Added link to Flickr API doc on photo source URLs in jdoc.
// 091116e- aha42 - Methods for 'Web Page URLs'.
// 091116d- aha42 - createPhotoHtmlLink(String, String, String, String).
// 091117 - aha42 - Added link to Flickr API doc on web URLs in jdoc.
// 091121 - aha42 - Added project page link (google code) to header comment.
// 091210 - aha42 - IOException -> FlickrException.
// 091212 - aha42 - FLICKR_URL, PHOTOS_URL, PEOPLE_URL, 
//                  createStreamUrlSpec(String) and 
//                  createProfileUrlSpec(String).
//

package org.aha.mf4j;

import static org.aha.mf4j.Photos.checkPhotoFormat;
import static org.aha.mf4j.Photos.checkSize;

import org.aha.mf4j.response.FlickrObject;

/**
 * <p>
 *   Constants and utility methods of use when working with Flickr URLs.
 * </p>
 * @author Arne Halvorsen (aha42)
 */
public final class FlickrUrls 
{
  private FlickrUrls(){} // Utility pattern dictates private constructor.
  
  /**
   * <p>
   *   Flickr's URL.
   * </p>
   */
  public static final String FLICKR_URL="http://www.flickr.com/";
  
  /**
   * <p>
   *   Base for photo streams.
   * </p>
   */
  public static final String PHOTOS_URL=FLICKR_URL+"photos/";
  
  /**
   * <p>
   *   Base for profile pages.
   * </p>
   */
  public static final String PEOPLE_URL=FLICKR_URL+"people/";
  
  /**
   * <p>
   *   URL to use for REST Flickr requests.
   * </p>
   */
  public static final String REST_URL="http://api.flickr.com/services/rest/";
  
  /**
   * <p>
   *   URL for authentication.
   * </p>
   */
  public static final String AUTH_URL="http://flickr.com/services/auth/";
  
  /**
   * <p>
   *   Creates URL specification to photo in default size. 
   * </p>
   * <p>
   *   See section <i>Photo Source URLs</a> for details on the URL this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p>
   * @param photoFo {@link FlickrObject} of 
   *                {@link FlickrObject#getType() type} {@code photo} with 
   *                parsed response data of photo to create URL specification 
   *                for.
   * @return URL specification.
   * @throws IllegalArgumentException If {@code s} does not specify legal size. 
   * @throws FlickrException If fails.
   */
  public static String createPhotoUrlSpec(FlickrObject photoFo) 
    throws FlickrException
  {
    return createPhotoUrlSpec(photoFo, null);  
  }
  
  /**
   * <p>
   *   Creates URL specification to photo. 
   * </p>
   * <p>
   *   See section <i>Photo Source URLs</a> for details on the URLs this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p> 
   * @param photoFo {@link FlickrObject} of 
   *                {@link FlickrObject#getType() type} {@code photo} with 
   *                parsed response data of photo to create URL specification 
   *                for.
   * @param s       Single character 
   *                {@code String} that specifies image size, if {@code null}
   *                makes URL specification to default size.
   * @return URL specification.
   * @throws IllegalArgumentException If {@code s} does not specify legal size. 
   * @throws FlickrException If fails.
   */
  public static String createPhotoUrlSpec(FlickrObject photoFo, String s) 
    throws FlickrException
  {
    if (photoFo==null)
    {
      throw new NullPointerException("photoFo");
    }
    
    photoFo.assertType("photo");
    
    String farm=photoFo.getMandatoryAttribute("farm");
    String server=photoFo.getMandatoryAttribute("server");
    String id=photoFo.getMandatoryAttribute("id");
    String secret=photoFo.getMandatoryAttribute("secret");
    
    return createPhotoUrlSpec(farm, server, id, secret, s);
  }
  
  /**
   * <p>
   *   Creates URL specification to photo in default size.
   * </p>
   * <p>
   *   See section <i>Photo Source URLs</a> for details on the URL this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p> 
   * @param farm   Farm id.
   * @param server Server id.
   * @param id     Photo id.
   * @param secret Secret.
   * @return URL specification.
   */
  public static String createPhotoUrlSpec(String farm, String server, 
    String id, String secret)
  {
    return createPhotoUrlSpec(farm, server, id, secret);
  }
  
  /**
   * <p>
   *   Creates URL specification to photo.
   * </p>
   * <p>
   *   See section <i>Photo Source URLs</a> for details on the URLs this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p> 
   * @param farm   Farm id.
   * @param server Server id.
   * @param id     Photo id.
   * @param secret Secret.
   * @param s      Single character 
   *               {@code String} that specifies image size, if {@code null}
   *               makes URL specification to default size.
   * @return URL specification.
   * @throws IllegalArgumentException If {@code s} does not specify legal size. 
   */
  public static String createPhotoUrlSpec(String farm, String server, 
    String id, String secret, String s)
  {
    if (farm==null)
    {
      throw new NullPointerException("farm");
    }
    if (server==null)
    {
      throw new NullPointerException("server");
    }
    if (id==null)
    {
      throw new NullPointerException("id");
    }
    if (secret==null)
    {
      throw new NullPointerException("secret");
    }
    
    if (s!=null) checkSize(s);
    
    StringBuilder sb=new StringBuilder("http://farm");
    
    sb.append(farm).append(".static.flickr.com/").append(server).append('/')
      .append(id).append('_').append(secret);
    if (s!=null) sb.append('_').append(s);
    sb.append(".jpg");
    
    return sb.toString();
  }
  
  /**
   * <p>
   *   Creates URL specification to original photo.
   * </p>
   * <p>
   *   See section <i>Photo Source URLs</a> for details on the URL this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p> 
   * @param farm    Farm id.
   * @param server  Server id.
   * @param id      Photo id.
   * @param osecret Original secret.
   * @param format  Format, if {@code null} assumes "jpg".
   * @return URL specification.
   * @throws IllegalArgumentException If {@code format} not {@code null} but 
   *         does not specify legal format. 
   */
  public static String createOrgPhotoUrlSpec(String farm, String server, 
    String id, String osecret, String format)
  {
    if (farm==null)
    {
      throw new NullPointerException("farm");
    }
    if (server==null)
    {
      throw new NullPointerException("server");
    }
    if (id==null)
    {
      throw new NullPointerException("id");
    }
    if (osecret==null)
    {
      throw new NullPointerException("osecret");
    }
    
    format=(format==null) ? "jpg" : format;
    checkPhotoFormat(format);
      
    StringBuilder sb=new StringBuilder("http://farm");
      
    sb.append(farm).append(".static.flickr.com/").append(server).append('/')
      .append(id).append('_').append(osecret).append("_o.").append(format);
   
    return sb.toString();
  }
  
  /**
   * <p>
   *   Creates URL specification for an user's profile page.
   * </p>
   * <p>
   *   See section <i>Web Page URLs</a> for details on the URL this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p> 
   * @param nsid User's id.
   * @return URL specification.
   */
  public static String createProfileWebUrlSpec(String nsid)
  {
    if (nsid==null)
    {
      throw new NullPointerException("nsid");
    }
    
    return "http://www.flickr.com/people/"+nsid;
  }
  
  /**
   * <p>
   *   Creates URL specification for an user's profile page.
   * </p>
   * <p>
   *   See section <i>Web Page URLs</a> for details on the URL this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p> 
   * @param nsid User's id.
   * @return URL specification.
   */
  public static String createPhotoStreamWebUrlSpec(String nsid)
  {
    if (nsid==null)
    {
      throw new NullPointerException("nsid");
    }
    
    return "http://www.flickr.com/photos/"+nsid;
  }
  
  /**
   * <p>
   *   Creates URL specification for an user's photo's URL. 
   * </p>
   * <p>
   *   See section <i>Web Page URLs</a> for details on the URL this method
   *   produce 
   *   <a href='http://www.flickr.com/services/api/misc.urls.html'>here</a>.
   * </p> 
   * @param nsid User's id.
   * @param id   Photo's id.
   * @return URL specification. 
   */
  public static String createPhotoWebUrlSpec(String nsid, String id)
  {
    if (nsid==null)
    {
      throw new NullPointerException("nsid");
    }
    if (id==null)
    {
      throw new NullPointerException("id");
    }
    
    return "http://www.flickr.com/photos/"+nsid+'/'+id;
  }
  
  /**
   * <p>
   *   Creates HTML code that is compliant with Flickr's 
   *   <a href='http://www.flickr.com/guidelines.gne'>guidelines</a> for 
   *   including an image of (Flickr) site.
   * </p>
   * @param nsid      User's id.
   * @param id        Photo's id.
   * @param sourceUrl Photo's source URL as produced by
   *                  {@link #createPhotoUrlSpec(String, String, String, String)},
   *                  {@link #createPhotoUrlSpec(String, String, String, String, String)},
   *                  {@link #createPhotoUrlSpec(FlickrObject)} or
   *                  {@link #createPhotoUrlSpec(FlickrObject, String)}.
   * @param title     Optional title for image, may be {@code null}.
   * @return HTML code.
   */
  public static String createPhotoHtmlLink(String nsid, String id, 
    String sourceUrl, String title)
  {
    if (nsid==null)
    {
      throw new NullPointerException("nsid");
    }
    if (id==null)
    {
      throw new NullPointerException("id");
    }
    if (sourceUrl==null)
    {
      throw new NullPointerException("sourceUrl");
    }
    
    String webUrl=createPhotoWebUrlSpec(nsid, id);
    
    StringBuilder sb=new StringBuilder();
    
    sb.append("<a href='").append(webUrl).append("'");
    
    if (title!=null) sb.append(" title='").append(title).append("'");
    
    sb.append("><img src='").append(sourceUrl).append("'");
    
    if (title!=null) sb.append(" alt='").append(title).append("'");
    
    sb.append("/></a>");
    
    return sb.toString();
  }
  
  /**
   * <p>
   *   Creates URL specification for an user's photo stream.
   * </p>
   * @param nsid User's id.
   * @return URL specification.
   */
  public static String createStreamUrlSpec(String nsid)
  {
    if (nsid==null)
    {
      throw new NullPointerException("nsid");
    }
    
    return PHOTOS_URL+nsid;
  }
  
  /**
   * <p>
   *   Creates URL specification for an user's profile page.
   * </p>
   * @param nsid User's id.
   * @return URL specification.
   */
  public static String createProfileUrlSpec(String nsid)
  {
    if (nsid==null)
    {
      throw new NullPointerException("nsid");
    }
    
    return PEOPLE_URL+nsid;
  }
  
}
